package com.aric.springbootmusic.jwt;

import com.aric.springbootmusic.entity.pojo.User;
import com.aric.springbootmusic.service.impl.UserDetailsImpl;
import io.jsonwebtoken.Claims;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.*;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;

public class JWTUtils {
    //生成JWT
    public static String generateJWT(){
        //如果用户名和密码正确，则SecurityContext中会有一个Authentication对象
        var authentication=SecurityContextHolder.getContext().getAuthentication();
        if(authentication!=null){
            UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
            User user = userDetails.getUser();
            //生成JWT
            SecretKey key= Keys.hmacShaKeyFor(SecurityConstants.JWT_KEY.getBytes(StandardCharsets.UTF_8));
            String jwt= Jwts.builder()
                    .issuer(authentication.getName()) //发送者
                    .subject(user.getId()) //主题
                    .claim("username",user.getUsername()) //断言 用户名
                    .claim("authorities",fillAuthorities(authentication.getAuthorities())) //断言 角色
                    .issuedAt(new Date()) //发布时间
                    .expiration(new Date(new Date().getTime()+1800000)) //有效期时间
                    .signWith(key) //用私钥加密
                    .compact(); //生成jwt
            return jwt;
        }
        return "";
    }
    //将授权信息转换为逗号分割的字符串
    private static String fillAuthorities(Collection<? extends GrantedAuthority> collection){
        Set<String> authorities=new HashSet<>();
        for (var auth : collection) {
            authorities.add(auth.getAuthority());
        }
        return String.join(",",authorities);
    }

    //使用私钥校验JWT的有效性，有效，返回true
    public static Claims getClaims(String jwt){
        //获取私钥
        SecretKey key=Keys.hmacShaKeyFor(SecurityConstants.JWT_KEY.getBytes(StandardCharsets.UTF_8));
        //提取JWT中包含的信息
        Claims claims=Jwts.parser().verifyWith(key).build().parseSignedClaims(jwt).getPayload();
        return claims;
    }
}
